const GRID_SIZE = 4;
const CELL_SIZE = 20;
const CELL_GAP = 2;

let grid;
let score = 0;
let highScore = localStorage.getItem('2048-highScore') || 0;
let musicEnabled = localStorage.getItem('2048-musicEnabled') !== 'false';
const bgm = document.getElementById('bgm');
const musicToggle = document.getElementById('music-toggle');

document.addEventListener('DOMContentLoaded', () => {
    setupGame();
    document.addEventListener('keydown', handleInput);
    
    // Initialize audio
    bgm.volume = 0.3;
    musicToggle.textContent = musicEnabled ? '音乐: 开' : '音乐: 关';
    
    // Start music after first user interaction
    const startMusic = () => {
        if (musicEnabled) {
            bgm.play();
        }
        document.removeEventListener('keydown', startMusic);
        document.removeEventListener('click', startMusic);
    };
    
    document.addEventListener('keydown', startMusic);
    document.addEventListener('click', startMusic);
    
    // Music toggle button
    musicToggle.addEventListener('click', () => {
        musicEnabled = !musicEnabled;
        localStorage.setItem('2048-musicEnabled', musicEnabled);
        if (musicEnabled) {
            bgm.play();
            musicToggle.textContent = '音乐: 开';
        } else {
            bgm.pause();
            musicToggle.textContent = '音乐: 关';
        }
    });
});

function setupGame() {
    grid = createGrid();
    score = 0;
    updateScore();
    document.getElementById('high-score').textContent = highScore;
    addNumber();
    addNumber();
}

function createGrid() {
    const grid = [];
    for (let i = 0; i < GRID_SIZE * GRID_SIZE; i++) {
        const cell = document.createElement('div');
        grid.push(cell);
        document.querySelector('.grid').append(cell);
    }
    return grid;
}

function addNumber() {
    const emptyCells = grid.filter(cell => !cell.textContent);
    if (emptyCells.length === 0) return;
    
    const randomCell = emptyCells[Math.floor(Math.random() * emptyCells.length)];
    randomCell.textContent = Math.random() > 0.5 ? 2 : 4;
    randomCell.className = `tile-${randomCell.textContent}`;
}

function handleInput(e) {
    switch (e.key) {
        case 'ArrowUp':
            move('up');
            break;
        case 'ArrowDown':
            move('down');
            break;
        case 'ArrowLeft':
            move('left');
            break;
        case 'ArrowRight':
            move('right');
            break;
        default:
            return;
    }
    if (isGameOver()) {
        document.querySelector('.game-over').style.display = 'flex';
    }
}

function move(direction) {
    let moved = false;
    
    // Process each row/column based on direction
    for (let i = 0; i < GRID_SIZE; i++) {
        const cells = getCells(direction, i);
        
        // First pass: move all tiles to one side
        const nonEmpty = cells.filter(cell => cell.textContent);
        const movedCells = [];
        for (let j = 0; j < nonEmpty.length; j++) {
            movedCells.push(nonEmpty[j]);
            // Add move animation
            nonEmpty[j].classList.add('move-animation');
            setTimeout(() => {
                nonEmpty[j].classList.remove('move-animation');
            }, 200);
        }
        
        // Fill remaining cells with empty
        while (movedCells.length < GRID_SIZE) {
            movedCells.push({textContent: '', className: ''});
        }
        
        // Second pass: merge adjacent tiles
        for (let j = 0; j < GRID_SIZE - 1; j++) {
            if (movedCells[j].textContent && 
                movedCells[j].textContent === movedCells[j + 1].textContent) {
                const newValue = parseInt(movedCells[j].textContent) * 2;
                movedCells[j].textContent = newValue.toString();
                movedCells[j].className = `tile-${newValue}`;
                movedCells[j + 1].textContent = '';
                movedCells[j + 1].className = '';
                score += newValue;
                moved = true;
                
                // Add merge animation
                movedCells[j].classList.add('merge-animation');
                setTimeout(() => {
                    movedCells[j].classList.remove('merge-animation');
                }, 200);
            }
        }
        
        // Third pass: move tiles again to fill gaps
        const finalCells = movedCells.filter(cell => cell.textContent);
        while (finalCells.length < GRID_SIZE) {
            finalCells.push({textContent: '', className: ''});
        }
        
        // Update the grid
        for (let j = 0; j < GRID_SIZE; j++) {
            cells[j].textContent = finalCells[j].textContent;
            cells[j].className = finalCells[j].className;
        }
    }
    
    if (moved) {
        updateScore();
        addNumber();
    } else {
        // Check if any moves are possible
        for (let i = 0; i < grid.length; i++) {
            if (!grid[i].textContent) {
                addNumber();
                break;
            }
        }
    }
}

function getCells(direction, index) {
    const cells = [];
    for (let i = 0; i < GRID_SIZE; i++) {
        let cell;
        switch (direction) {
            case 'up':
                cell = grid[index + i * GRID_SIZE];
                break;
            case 'down':
                cell = grid[index + (GRID_SIZE - 1 - i) * GRID_SIZE];
                break;
            case 'left':
                cell = grid[i + index * GRID_SIZE];
                break;
            case 'right':
                cell = grid[(GRID_SIZE - 1 - i) + index * GRID_SIZE];
                break;
        }
        cells.push(cell);
    }
    return cells;
}

function updateScore() {
    document.getElementById('score').textContent = score;
    if (score > highScore) {
        highScore = score;
        document.getElementById('high-score').textContent = highScore;
        localStorage.setItem('2048-highScore', highScore);
    }
}

function isGameOver() {
    for (let i = 0; i < grid.length; i++) {
        if (!grid[i].textContent) return false;
        if (i % GRID_SIZE !== GRID_SIZE - 1 && grid[i].textContent === grid[i + 1].textContent) return false;
        if (i < grid.length - GRID_SIZE && grid[i].textContent === grid[i + GRID_SIZE].textContent) return false;
    }
    return true;
}

function restartGame() {
    document.querySelector('.game-over').style.display = 'none';
    document.querySelector('.grid').innerHTML = '';
    setupGame();
}
